package com.java.item.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.java.common.dato.CartDTO;
import com.java.common.enums.ExceptionEnum;
import com.java.common.exception.CusException;
import com.java.common.utils.PageResult;
import com.java.item.dto.SpuDTO;
import com.java.item.entity.*;
import com.java.item.mapper.*;
import com.java.item.service.GoodsService;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author jl
 * @description
 * @date 2019-10-16 16:41
 */
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private SpuDao spuDao;
    @Autowired
    private BrandDao brandDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private SpuDetailDao spuDetailDao;
    @Autowired
    private SkuDao skuDao;
    @Autowired
    private StockDao stockDao;
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public PageResult<SpuDTO> querySpuByPage(String key, Boolean saleable, Integer page, Integer rows) {
        //分页查询条件,上下架条件
        IPage<Spu> spus = spuDao.selectPage(new Page<>(page, rows), new LambdaQueryWrapper<Spu>().like(StrUtil.isNotEmpty(key), Spu::getTitle, key).eq(saleable != null, Spu::getSaleable, saleable));
        //spu->spuDTO
        List<SpuDTO> spuDTOS = spus.getRecords().stream().map(spu -> {
            SpuDTO dto = new SpuDTO();
            BeanUtils.copyProperties(spu, dto);
            //查询品牌名称
            Brand brand = brandDao.selectById(spu.getBrandId());
            dto.setBname(brand.getName());
            //查询分类名称
            List<Category> categories = categoryDao.selectList(new LambdaQueryWrapper<Category>().in(Category::getId, Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3())));
            List<String> names = categories.stream().map(Category::getName).collect(Collectors.toList());
            dto.setCname(StrUtil.join("-", names));
            return dto;
        }).collect(Collectors.toList());
        //返回pageResult
        return new PageResult<>(spus.getTotal(),spus.getPages(),spuDTOS);
    }

    @Override
    @Transactional
    public void saveGoods(SpuDTO spuDTO) {
        //1.新增spu
        spuDTO.setId(null); //防止恶意刷接口
        spuDao.insert(spuDTO);
        //2.新增spuDetail
        SpuDetail spuDetail = spuDTO.getSpuDetail();
        spuDetail.setSpuId(spuDTO.getId());
        spuDetailDao.insert(spuDetail);
        saveSkuAndStock(spuDTO);

        sendMsg("insert", spuDTO.getId());

    }

    @Override
    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        //根据spuId查询该spu下的sku
        List<Sku> skus = skuDao.selectList(new LambdaQueryWrapper<Sku>().eq(Sku::getSpuId, spuDTO.getId()));
        List<Long> skuIds = skus.stream().map(Sku::getId).collect(Collectors.toList());
        //删除stock
        stockDao.deleteBatchIds(skuIds);
        //删除sku
        skuDao.deleteBatchIds(skuIds);
        //新增sku和stock
        saveSkuAndStock(spuDTO);
        //更新spu和spuDetail
        spuDTO.setCreateTime(null);
        spuDTO.setLastUpdateTime(new Date());
        spuDTO.setValid(null);
        spuDTO.setSaleable(null);
        spuDao.updateById(spuDTO);
        spuDetailDao.updateById(spuDTO.getSpuDetail());

        sendMsg("update", spuDTO.getId());

    }

    private void saveSkuAndStock(SpuDTO spuDTO) {
        spuDTO.getSkus().forEach(sku->{
            //3.新增sku
            sku.setId(null);
            sku.setSpuId(spuDTO.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(new Date());
            skuDao.insert(sku);
            //4.新增stock
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            stockDao.insert(stock);
        });
    }

    private void sendMsg(String type,Long id) {
        //发送消息
        try {
            //使用yml中配置的交换机
            amqpTemplate.convertAndSend("item."+ type, id);
        } catch (AmqpException e) {
            e.printStackTrace();
        }
    }

    @Override
    public SpuDetail queryDetailBySpuId(Long spuId) {
        return spuDetailDao.selectById(spuId);
    }

    @Override
    public List<Sku> querySkusBySpuId(Long spuId) {
        return skuDao.querySkusBySpuId(spuId);
    }

    @Override
    public Spu querySpuById(Long id) {
        return spuDao.selectById(id);
    }

    @Override
    public Sku querySkuBySkuId(Long skuId) {
        return skuDao.selectById(skuId);
    }

    @Override
    public void decreaseStock(List<CartDTO> carts) {
        for (CartDTO cart : carts) {
            //减库存
            int affectedRow = stockDao.decreaseStock(cart.getSkuId(), cart.getNum());
            if (affectedRow != 1)
                throw new CusException(ExceptionEnum.STOCK_NOT_ENOUGH.getMsg());
        }
    }
}
